﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Lucene.Net.Index;
using Lucene.Net.Documents;
using ObjectSearch.Configuration;

namespace ObjectSearch
{
    public class LuceneIndexWriter<T> : LuceneObjectSearchBase, IIndexWriter
    {
        /// <summary>
        /// A private field used to hold the value for Writer property.
        /// </summary>
        private Lucene.Net.Index.IndexWriter _Writer;

        public Lucene.Net.Index.IndexWriter Writer
        {
            get
            {
                return _Writer;
            }
        }

        public LuceneIndexWriter(IndexSettings settings, Configuration.Configuration configuration)
            : base(settings, configuration)
        {
            if (!IndexReader.IndexExists(settings.Directory))
            {
                _Writer = new IndexWriter(settings.Directory, settings.Analyzer, true);
            }
            else
            {
                _Writer = new IndexWriter(settings.Directory, settings.Analyzer, false);
            }

            _Writer.SetMaxBufferedDocs(2000);
        }

        #region IIndexWriter Members

        public void Insert(object item)
        {
            Document luceneDocument = Converter.ObjectToDocumentConverter.Convert(item, Configuration);

            Writer.AddDocument(luceneDocument);
        }

        public void Update(object item)
        {
            this.Delete(item);
            this.Insert(item);
        }

        public void Delete(object item)
        {
            Type objectType = typeof(T);

            IndexReader indexReader = IndexReader.Open(IndexSettings.Directory);
            FieldMetaData keyField = Configuration.FindMetaData(objectType).FindKeyField();

            Document d = Converter.ObjectToDocumentConverter.Convert(item, Configuration);
            string v = d.GetValues(keyField.FieldName)[0];

            Term deletionTerm = new Term(keyField.FieldName, v);
            int numberDelete = indexReader.DeleteDocuments(deletionTerm);

            indexReader.Close();
        }

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            Writer.Optimize();
            Writer.Close();
        }

        #endregion
    }
}
